package com.qcxk.yuqian.system.service.imp;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcxk.yuqian.system.entity.*;
import com.qcxk.yuqian.system.mapper.AuthMapper;
import com.qcxk.yuqian.system.mapper.RoleAuthMapper;
import com.qcxk.yuqian.system.mapper.UserRoleMapper;
import com.qcxk.yuqian.system.mapper.UserauthorderMapper;
import com.qcxk.yuqian.system.service.AuthService;
import com.qcxk.yuqian.system.utils.ThmsUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class AuthServiceImp extends ServiceImpl<AuthMapper, Auth> implements AuthService {
    @Autowired
    private AuthMapper authMapper;
    @Autowired
    private RoleAuthMapper roleAuthMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private UserauthorderMapper userauthorderMapper;

    public Integer getRootId(JSONObject authMap, Integer id) {
        JSONObject auth = (JSONObject) authMap.get(id + "");
        if (auth.getInteger("parentId") != 0) {
            return getRootId(authMap, auth.getInteger("parentId"));
        } else {
            return auth.getInteger("id");
        }
    }

    public void putParent(Object item, int parentId, JSONObject rootJSON) {
        if (rootJSON.containsKey("childList")) {
            JSONArray childList = rootJSON.getJSONArray("childList");
            for (Object json : childList) {
                JSONObject jsonObject = (JSONObject) json;
                if (jsonObject.getInteger("id") == parentId) {
                    JSONArray jsonArray;
                    if (jsonObject.containsKey("childList")) {
                        jsonArray = jsonObject.getJSONArray("childList");
                    } else {
                        jsonArray = new JSONArray();
                        jsonObject.put("childList", jsonArray);
                    }
                    jsonArray.add(JSONObject.toJSON(item));
                    return;
                }
            }
            for (Object json : childList) {
                JSONObject jsonObject = (JSONObject) json;
                putParent(item, parentId, jsonObject);
            }
        }
    }

    @Override
    public List<JSONObject> queryAllList(Integer userId) {
        List<Auth> auths = authMapper.selectList(null);
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.eq("user_id", userId);
        UserRole userRole = userRoleMapper.selectOne(userRoleQueryWrapper);
        if (userRole != null) {
            List<RoleAuth> roleAuths = roleAuthMapper.selectList(new QueryWrapper<RoleAuth>().eq("role_id", userRole.getRoleId()));
            JSONObject authJSON = new JSONObject();

            for (Auth auth : auths) {
                JSONObject authJO = (JSONObject) JSONObject.toJSON(auth);
                authJO.put("hasAuth", "1");//没有
                int id = auth.getId();
                for (RoleAuth item : roleAuths) {
                    int authId = item.getAuthId();
                    if (id == authId) {
                        authJO.put("hasAuth", "0");//有
                    }
                }
                authJSON.put("" + auth.getId(), authJO);
            }

            List<JSONObject> list = getAuthJSONTree(authJSON, auths);
            return list;
        } else {
            return null;
        }

    }

    @Override
    public List<JSONObject> queryAllList() {
        List<Auth> auths = authMapper.selectList(null);
        JSONObject authJSON = new JSONObject();

        for (Auth auth : auths) {
            JSONObject authJO = (JSONObject) JSONObject.toJSON(auth);
            authJSON.put("" + auth.getId(), authJO);
        }

        List<JSONObject> list = getAuthJSONTree(authJSON, auths);
        return list;


    }

    @Override
    public boolean addAuth(Auth auth) {
        auth.setCtime(ThmsUtil.getDate());
        int re = authMapper.insert(auth);
        return re == 1 ? true : false;
    }

    @Override
    public boolean updateAuth(Auth auth) {
        Auth item = authMapper.selectById(auth.getId());
        if (StringUtils.isNotBlank(auth.getName())) {
            item.setName(auth.getName());
        }
        if (StringUtils.isNotBlank(auth.getDescription())) {
            item.setDescription(auth.getDescription());
        }
        if (StringUtils.isNotBlank(auth.getGrantAuth())) {
            item.setGrantAuth(auth.getGrantAuth());
        }
        if (StringUtils.isNotBlank(auth.getIcon())) {
            item.setIcon(auth.getIcon());
        }
        if (StringUtils.isNotBlank(auth.getUrl())) {
            item.setUrl(auth.getUrl());
        }
        if (0 != auth.getParentId() && null != auth.getParentId()) {
            item.setParentId(auth.getParentId());
        }
        if (StringUtils.isNotBlank(auth.getType())) {
            item.setType(auth.getType());
        }
        int re = authMapper.updateById(item);
        return re == 1 ? true : false;
    }

    @Override
    public List<Auth> getBtnList(Integer userId) {
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.eq("user_id", userId);
        UserRole userRole = userRoleMapper.selectOne(userRoleQueryWrapper);
        List<Auth> btns = new ArrayList<>();
        if (userRole != null) {
            QueryWrapper<RoleAuth> roleAuthQueryWrapper = new QueryWrapper<>();
            roleAuthQueryWrapper.eq("role_id", userRole.getRoleId());
            List<RoleAuth> roleAuths = roleAuthMapper.selectList(roleAuthQueryWrapper);
            QueryWrapper<Auth> authQueryWrapper = new QueryWrapper<>();
            authQueryWrapper.eq("type", "1");
            List<Auth> auths = authMapper.selectList(authQueryWrapper);

            for (Auth item : auths) {
                for (RoleAuth temp : roleAuths) {
                    if (item.getId().intValue() == temp.getAuthId().intValue()) {
                        btns.add(item);
                        break;
                    }
                }
            }
        }
        return btns;
    }

    /**
     * 通过authList生成jsontree
     *
     * @param auths 所有菜单的list
     * @return
     */
    private List<JSONObject> getAuthJSONTree(JSONObject authMap, List<Auth> auths) {

        JSONObject authJson = new JSONObject();
        for (Auth item : auths) {
            int parentId = item.getParentId();
            if (parentId == 0) {
                authJson.put("" + item.getId(), authMap.get("" + item.getId()));
            } else {
                int rootId = getRootId(authMap, item.getId());
                JSONObject parentJSON = (JSONObject) authJson.get(rootId + "");
                JSONArray childList;
                if (parentId == rootId) {
                    if (parentJSON.containsKey("childList")) {
                        childList = parentJSON.getJSONArray("childList");
                    } else {
                        childList = new JSONArray();
                    }
                    childList.add(authMap.get("" + item.getId()));
                    parentJSON.put("childList", childList);
                } else {
                    putParent(authMap.get("" + item.getId()), parentId, parentJSON);
                }
            }
        }
        Collection values = authJson.values();
        return new ArrayList<JSONObject>(values);
    }

    @Override
    public List<JSONObject> queryUserAuthList(Integer userId) {
        QueryWrapper<Auth> authQueryWrapper = new QueryWrapper<>();
        authQueryWrapper.orderByAsc("order_no", "id");
        List<Auth> auths = authMapper.selectList(null);
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.eq("user_id", userId);
        UserRole userRole = userRoleMapper.selectOne(userRoleQueryWrapper);
        if (userRole != null) {
            QueryWrapper<Userauthorder> userauthorderQueryWrapper = new QueryWrapper<>();
            userauthorderQueryWrapper.eq("user_id", userId);
            //从数据库查询出来的菜单顺序
            List<Userauthorder> userauthorders = userauthorderMapper.selectList(userauthorderQueryWrapper);
            //数据库没存的菜单顺序，存入这个List，然后插入数据库--第一次登录的时候
            List<Userauthorder> userauthorderList = new ArrayList<>();
            Map<Integer, Userauthorder> userauthorderMap = new HashMap<>();
            for (Userauthorder item : userauthorders) {
                item.setTodo("0");//都标识为需要删除
                userauthorderMap.put(item.getAuthId(), item);
            }
            List<RoleAuth> roleAuths = roleAuthMapper.selectList(new QueryWrapper<RoleAuth>().eq("role_id", userRole.getRoleId()));
            JSONObject authJSON = new JSONObject();
            List<Auth> authsUser = new ArrayList<>();
            for (Auth auth : auths) {
                JSONObject authJO = (JSONObject) JSONObject.toJSON(auth);
                int id = auth.getId();
                for (RoleAuth item : roleAuths) {
                    int authId = item.getAuthId();
                    if (id == authId) {
                        if (auth.getParentId().equals(0)) {
                            if (userauthorderMap.containsKey(authId)) {
                                authJO.put("orderNo", userauthorderMap.get(authId).getOrderNum());
                                authJO.put("often", userauthorderMap.get(authId).getOften());
                                Userauthorder userauthorder = userauthorderMap.get(authId);
                                userauthorder.setTodo("2");//不需要删除
                                userauthorderList.add(userauthorder);
                            } else {
                                Userauthorder userauthorder = new Userauthorder();
                                userauthorder.setAuthId(authId);
                                userauthorder.setUserId(userId);
                                userauthorder.setTodo("1");
                                userauthorder.setOrderNum(userauthorders.size() + userauthorderList.size() + 1);
                                userauthorder.setOften(userauthorderList.size() >= 6 ? "1" : "0");
                                userauthorderList.add(userauthorder);
                                authJO.put("orderNo", userauthorder.getOrderNum());
                                authJO.put("often", userauthorder.getOften());
                            }
                        }
                        authJSON.put("" + auth.getId(), authJO);
                        authsUser.add(auth);

                    }
                }
            }

            List<JSONObject> list = getAuthJSONTree(authJSON, authsUser);
            //把没有排序的菜单排序并插入数据库，下次查询就按这个顺序展示
            userauthorderList.parallelStream().forEach(e -> {
                if (e.getTodo().equals("0")) {//进行删除操作
                    userauthorderList.remove(e);
                    userauthorderMapper.deleteById(e.getId());
                }
            });
            for (int i = 0; i < userauthorderList.size(); i++) {
                Userauthorder item = userauthorderList.get(i);
                if (i < 6) {
                    item.setOften("0");
                } else {
                    item.setOften("1");
                }
                if (item.getTodo().equals("1")) {
                    userauthorderMapper.insert(item);
                }
            }
            return list;
        } else {
            return null;
        }

    }

    @Override
    public List<JSONObject> queryRoleAuthList(Integer id) {
        List<Auth> auths = authMapper.selectList(null);
        List<RoleAuth> roleAuths = roleAuthMapper.selectList(new QueryWrapper<RoleAuth>().eq("role_id", id));
        JSONObject authJSON = new JSONObject();

        for (Auth auth : auths) {
            JSONObject authJO = (JSONObject) JSONObject.toJSON(auth);
            authJO.put("hasAuth", "1");//没有
            int aid = auth.getId();
            for (RoleAuth item : roleAuths) {
                int authId = item.getAuthId();
                if (aid == authId) {
                    authJO.put("hasAuth", "0");//有
                }
            }
            authJSON.put("" + auth.getId(), authJO);
        }

        List<JSONObject> list = getAuthJSONTree(authJSON, auths);
        return list;
    }
}
